package controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.NoArgsConstructor;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import pojo.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static java.lang.System.out;

@Controller
public class ExamController {

    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    HttpSession session;
    int t_id;//教师编号
    int s_id;//学生编号


    public ExamController() throws IOException {
    }

    //跳转到教师查看成绩页面
    @RequestMapping("/toteacher_score")
    public String toTeacher_scorePage() {
        return "teacher_score.jsp";
    }

    //跳转到学生考试页面
    @RequestMapping("/toexam")
    public String toExam() {
        return "exam.jsp";
    }

    //所有生成的试卷
    @RequestMapping(value = "/loadPublishList")
    public String loadPublishList(HttpSession session) throws Exception {
        t_id = (int) session.getAttribute("TEACHER_ID");
        sqlSession.close();
        sqlSession=sqlSessionFactory.openSession();
        List<Paper> teacher_exam = sqlSession.selectList("mapper.Paper.findAllPapers", t_id);//查询教师所有的试卷
        session.setAttribute("teacher_exam", teacher_exam);
        return "teacher_publish.jsp";
    }

    //该老师所有试卷的成绩
    @RequestMapping(value = "/loadScoreList")
    public String loadScoreList(HttpSession session) throws Exception {
        t_id = (int) session.getAttribute("TEACHER_ID");
        List<Score> score = sqlSession.selectList("mapper.Score.findTeacherScores", t_id);//查询教师已发布的试卷的所有成绩
        session.setAttribute("score", score);
        return "teacher_score.jsp";
    }

    //该老师发布的此场考试的所有学生的成绩
    @RequestMapping(value = "/loadMyStudentsScoreList")
    public String loadMyStudentsScoreList(HttpSession session) throws Exception {
        int p_id = (int) session.getAttribute("my_p_id");//获取这门考试的id
        List<Score> all_studentsScore = sqlSession.selectList("mapper.Score.findAllStudentsScore", p_id);//获取参加这门考试的学生的所有成绩
        for (Score c : all_studentsScore) {//获取学生姓名
            Student student = sqlSession.selectOne("mapper.Student.findStudentByStudentIds", c.getS_id());
            session.setAttribute("name" + c.getS_id(), student.getS_name());
        }
        session.setAttribute("all_studentsScore", all_studentsScore);
        return "teacher_search_score.jsp";
    }

    //学生的所有试卷（教师发布了学生才能看到）
    @RequestMapping(value = "/loadStudentExamList")
    public String loadStudentExamList(HttpSession session) throws Exception {
        out.println("sile");
        if (session.getAttribute("STUDENT_ID") == null) {
            out.println("获取学生id失败");
        } else {
            s_id = (int) session.getAttribute("STUDENT_ID");
            List<Paper> student_exam = sqlSession.selectList("mapper.Paper.findStudentExams", s_id);//这位学生的所有老师已经发布的所有试卷
            session.setAttribute("student_exam", student_exam);

        }
        return "student_take_exam.jsp";
    }

    //学生写过的所有试卷的成绩
    @RequestMapping(value = "/loadMyScoreList")
    public String loadMyScoreList(HttpSession session) throws Exception {
        s_id = (int) session.getAttribute("STUDENT_ID");
        List<Score> student_score = sqlSession.selectList("mapper.Score.findStudentScores", s_id);//这位学生已经参加过的试卷的成绩
        session.setAttribute("student_score", student_score);
        return "student_score.jsp";
    }

    //该学生参加的考试的试卷内容
    @RequestMapping(value = "/loadMyExamList")
    public String loadMyExamList(HttpSession session) throws Exception {
        int exam_id = (int) session.getAttribute("exam_id");//获取试卷id
        List<Point> exam_contents = sqlSession.selectList("mapper.Point.findMyExamContents", exam_id);//这位学生参加的试卷的内容
        session.setAttribute("exam_contents", exam_contents);
        Paper exam_time = sqlSession.selectOne("mapper.Paper.findPaperTimeById", exam_id);//这位学生参加的考试试卷的结束时间和试卷名
        long createTime = exam_time.getEndtime().getTime();//获取开始时间的时间戳
        long currentTime = System.currentTimeMillis();//获取当前时间的时间戳
        long diff = (createTime - currentTime) / 1000 / 60;//获取两个时间相差的小时
        session.setAttribute("duration_time", diff);//给前端做倒计时处理
        session.setAttribute("end_time", exam_time.getEndtime());//给前端做倒计时处理
        int sum = 0;//该试卷的题目数量
        float full_marks = 0;//满分
        for (Point c : exam_contents) {//计算题数和总分
            sum++;
            full_marks += c.getMark();
        }
        session.setAttribute("sum", sum);
        session.setAttribute("full_marks", full_marks);
        session.setAttribute("exam_name", exam_time.getP_name());
        return "exam.jsp";
    }

    //学生的所有错题
    @RequestMapping(value = "/loadMistakesList")
    public String loadMistakesList(HttpSession session) throws Exception {
        s_id = (int) session.getAttribute("STUDENT_ID");
        List<Answer> student_mistakes = sqlSession.selectList("mapper.Answer.findAllMistakes", s_id);//查询学生所有的错题信息
        session.setAttribute("student_mistakes", student_mistakes);
        return "collected_mistakes.jsp";
    }

    //老师发布的试卷中，参加这门试卷的学生的成绩
    @RequestMapping(value = "/LoadListScore")
    @ResponseBody
    public Boolean LoadListScore(String name, HttpSession session) throws Exception {
        t_id = (int) session.getAttribute("TEACHER_ID");
        String name1 = name.trim();
        int p_id = sqlSession.selectOne("mapper.Paper.findPaperIdByName", name1);//获取试卷的id
        session.setAttribute("my_p_id", p_id);
        session.setAttribute("my_p_name", name1);
        List<Score> all_studentsScore = sqlSession.selectList("mapper.Score.findAllStudentsScore", p_id);//获取参加这门考试的学生的所有成绩
        session.setAttribute("all_studentsScore", all_studentsScore);
        return true;
    }

    //    教师发布试卷
    @RequestMapping(value = "/publish")
    @ResponseBody
    public boolean teacher_publish(HttpSession session, String name) throws IOException {
        String p_name = name.trim();//去除多余的空格
        Paper paper = new Paper();
        paper.setP_name(p_name);
        t_id = (int) session.getAttribute("TEACHER_ID");
        paper.setT_id(t_id);
        out.println(t_id);
        out.println(name);
        Paper ps = sqlSession.selectOne("mapper.Paper.findIf_PublishBrByP_Name", paper);//通过试卷名字查找该试卷是否发布

        int p_id = ps.getP_id();
        if (ps.getIfpublish() == 0) {//试卷还未发布
            List<Integer> all_s_id = sqlSession.selectList("mapper.Course.findS_idByTeacherId", t_id);
            for (int i : all_s_id) {//将该老师的所有学生的这门试卷的成绩改为-1；
                Score score = new Score();
                score.setS_id(i);//设置学号
                score.setP_id(p_id);//设置试卷id
                int s = sqlSession.insert("mapper.Score.InsertInitialScore", score);
                if (s > 0) {
                } else {
                }
                sqlSession.commit();
            }
            paper.setIfpublish(1);
            int rows = sqlSession.update("mapper.Paper.SetPublish", paper);//更新为已发布
            sqlSession.commit();
            if (rows > 0) {
                out.println("更改试卷的发布状态成功");

            } else {
                out.println("更改试卷的发布状态失败");
            }
            return false;
        } else {//已发布
            return true;
        }

    }

    //    在教师发布页面查询试卷
    @RequestMapping(value = "/search_publish")
    public String getExamName(Paper paper, HttpSession session) throws IOException {
        Paper pp = new Paper();
        t_id = (int) session.getAttribute("TEACHER_ID");
        pp.setT_id(t_id);
        pp.setP_name(paper.getP_name());
        List<Paper> teacher_exam = sqlSession.selectList("mapper.Paper.findTeacherPaperByP_Name", pp);
        if (teacher_exam == null) {
            out.println("数据为空");
        } else {
            session.setAttribute("teacher_exam", teacher_exam);
        }
        return "teacher_publish.jsp";
    }

    //    在教师查看成绩页面查询试卷
    @RequestMapping(value = "/search_Teacherscore")
    public String getScoreName(Paper paper, HttpSession session) throws IOException {
        Paper pp = new Paper();
        t_id = (int) session.getAttribute("TEACHER_ID");
        pp.setT_id(t_id);
        pp.setP_name(paper.getP_name());
        List<Score> ss = sqlSession.selectList("mapper.Score.findTeacherScoresByName", pp);
        if (ss == null) {//查找为空
            out.println("数据为空");
        } else {
            session.setAttribute("score", ss);
        }
        return "teacher_score.jsp";
    }

    //    在学生参加考试页面查询试卷
    @RequestMapping(value = "/search_StudentExam")
    public String search_StudentExam(Paper paper, HttpSession session) throws IOException {
        Paper pp = new Paper();
        s_id = (int) session.getAttribute("STUDENT_ID");
        pp.setS_id(s_id);//设置该学生的学号
        pp.setP_name(paper.getP_name());//设置搜素的试卷的名字
        List<Paper> student_examByname = sqlSession.selectList("mapper.Paper.findStudentPaperByP_Name", pp);//找到包含该名字的试卷
        if (student_examByname == null) {//查找为空
            out.println("数据为空");
        } else {
            session.setAttribute("student_exam", student_examByname);//设置找到的试卷为session对象
        }
        return "student_take_exam.jsp";
    }

    //    在学生查看成绩页面通过试卷名查询试卷的成绩
    @RequestMapping(value = "/search_StudentScore")
    public String search_StudentScore(Paper paper, HttpSession session) throws IOException {
        Paper pp = new Paper();
        s_id = (int) session.getAttribute("STUDENT_ID");
        pp.setS_id(s_id);//设置该学生的学号
        String p_name = paper.getP_name().trim();
        pp.setP_name(p_name);//设置搜素的试卷的名字
        List<Score> student_scoreByName = sqlSession.selectList("mapper.Score.findStudentScoreByName", pp);//找到包含该名字的试卷
        if (student_scoreByName == null) {//查找为空
            out.println("数据为空");
        } else {
            session.setAttribute("student_score", student_scoreByName);//设置找到的试卷为session对象
        }
        return "student_score.jsp";
    }

    //    在teacher_search_score页面通过学生姓名查询该学生该试卷的成绩
    @RequestMapping(value = "/search_StudentScoreBys_name")
    public String search_StudentScoreBys_name(Paper paper, HttpSession session) throws IOException {
        Paper p = new Paper();
        p.setS_name(paper.getS_name());
        int p_id = (int) session.getAttribute("my_p_id");
        p.setP_id(p_id);
        List<Score> student_scoreBys_name = sqlSession.selectList("mapper.Score.findStudentsScoreBys_name", p);//找到包含该名字的试卷
        for (Score c : student_scoreBys_name) {//获取学生姓名
            Student student = sqlSession.selectOne("mapper.Student.findStudentByStudentId", c.getS_id());
            session.setAttribute("name" + c.getS_id(), student.getS_name());
        }
        if (student_scoreBys_name == null) {//查找为空
            out.println("数据为空");
        } else {
            session.setAttribute("all_studentsScore", student_scoreBys_name);//设置找到的试卷为session对象
        }
        return "teacher_search_score.jsp";
    }

    //    在检查学生是否参加过这场考试
    @RequestMapping(value = "/takeinexam")
    @ResponseBody
    public String IfTakeInExam(String exam_name, HttpSession session, HttpServletResponse resp) throws
            IOException, ParseException {
        String name = exam_name.trim();
        int p_id = sqlSession.selectOne("mapper.Paper.findPaperIdByName", name);//通过试卷名查找试卷id
        Paper paper = sqlSession.selectOne("mapper.Paper.findPaperTimeById", p_id);//获取该试卷的开始时间和结束时间
        Score sc = new Score();
        sc.setP_id(p_id);
        s_id = (int) session.getAttribute("STUDENT_ID");
        sc.setS_id(s_id);
        float score = sqlSession.selectOne("mapper.Score.findStudentScore", sc);//查找学生的成绩
        if (score != -1) {//已经参加过考试
            return "true";
        } else {//还没参加过考试
            long startTime = paper.getStarttime().getTime();//获取开始时间的时间戳
            long endTime = paper.getEndtime().getTime();//获取开始时间的时间戳
            long currentTime = System.currentTimeMillis();//获取当前时间的时间戳
            long diff1 = (currentTime - startTime) / 1000 / 60;//获取开始时间和现在的时间相差的分钟
            long diff2 = (currentTime - endTime) / 1000 / 60;//获取结束时间和现在的时间相差的分钟
            session.setAttribute("exam_id", p_id);//所要参加的考试名
            if (diff2 >= 0) {
                out.println("该试卷的结束时间已过");
                return "overTime";
            } else if (diff1 < 0) {
                out.println("该试卷的开始时间还未到");
                return "preTime";
            }
            return "false";
        }
    }

    //    在学生错题页面通过题目查询错题
    @RequestMapping(value = "/search_StudentMistakes")
    public String search_StudentMistakes(Question question, HttpSession session) throws IOException {
        Question question1 = new Question();
        s_id = (int) session.getAttribute("STUDENT_ID");
        question1.setS_id(s_id);//设置该学生的学号
        String q_content = question.getQ_content().trim();
        question1.setQ_content(q_content);//设置搜素的题目
        List<Answer> student_mistakes = sqlSession.selectList("mapper.Answer.findMistakesByContents", question1);//找到包含该名字的题目
        if (student_mistakes == null) {//查找为空
            out.println("数据为空");
        } else {
            session.setAttribute("student_mistakes", student_mistakes);//设置找到的题目为session对象
        }
        return "collected_mistakes.jsp";
    }

    //    将学生的选项传入数据库并判断是否正确
    @RequestMapping(value = "/SubmitAnswer", method = RequestMethod.POST)
    @ResponseBody
    public boolean SubmitAnswer(@RequestBody Map<Integer, Object> map, HttpSession session, Model model) throws
            IOException, ParseException {
        s_id = (int) session.getAttribute("STUDENT_ID");
        float sum_score = 0;
        int exam_id = (int) session.getAttribute("exam_id");//获取试卷id
        for (Integer key : map.keySet()) {
            Answer answer = new Answer();//一条作答记录
            answer.setQ_id(key);//设置题号
            if (map.get(key) == null) {
                answer.setS_op("null");//设置选择的选项为空
            } else {
                answer.setS_op(map.get(key).toString());//设置选择的选项
            }
            answer.setS_id(s_id);//设置该学生
            answer.setP_id(exam_id);
            int rows = sqlSession.update("mapper.Answer.InsertIntoAnswer", answer);//插入作答表
            sqlSession.commit();
            if (rows > 0) {//插入成功
            } else {//插入失败
            }
            Point point = new Point();
            point.setP_id(exam_id);
            point.setQ_id(key);
            float mark = sqlSession.selectOne("mapper.Point.SearchPoint", point);
            String right_answer = sqlSession.selectOne("mapper.Question.searchQ_Standard", key);//找到该题目的正确答案
            if (right_answer.trim().equals(map.get(key))) {//回答正确
                sum_score += mark;//加上该题分值
            } else {
            }
        }
        Paper paper = sqlSession.selectOne("mapper.Paper.findPaperTimeById", exam_id);
        long createTime = paper.getStarttime().getTime();//获取开始时间的时间戳
        long currentTime = System.currentTimeMillis();//获取当前时间的时间戳
        long diff = (currentTime - createTime) / 1000 / 60;//获取两个时间相差的分钟
        int answertime = (int) diff;//作答时间
        Score score = new Score();
        score.setScore(sum_score);//得分
        score.setS_id(s_id);//学号
        score.setP_id(exam_id);//试卷号
        score.setAnswertime(answertime);//回答时间
        int rows = sqlSession.update("mapper.Score.InsertStudentScoreAndTime", score);//更新成绩表的成绩和作答时间
        if (rows > 0) {
            out.println("成绩和时间插入成功");
        }
        sqlSession.commit();
        return true;
    }

    //学生查看批改过的试卷
    @RequestMapping(value = "/toCorrectedExam")
    @ResponseBody
    public Boolean toCorrectedExam(HttpSession session, String name) throws IOException {
        s_id = (int) session.getAttribute("STUDENT_ID");//学生id
        Student student = sqlSession.selectOne("mapper.Student.findStudentByStudentId", s_id);
        int corrected_exam_id = sqlSession.selectOne("mapper.Paper.findPaperIdByName", name.trim());//获取试卷id
        List<Point> exam_contents = sqlSession.selectList("mapper.Point.findMyExamContents", corrected_exam_id);//批改后的的试卷的内容
        session.setAttribute("corrected_exam_contents", exam_contents);
        float full_marks = 0;//满分
        for (Point c : exam_contents) {
            full_marks += c.getMark();//计算满分
            String right_answer = sqlSession.selectOne("mapper.Question.searchQ_Standard", c.getQ_id());//找到该题目的正确答案
            Answer answer = new Answer();
            answer.setS_id(s_id);//设置学号
            answer.setQ_id(c.getQ_id());//设置题号
            answer.setP_id(corrected_exam_id);//设置试卷号
            String s_answer = sqlSession.selectOne("mapper.Answer.SearchAnswer", answer);//获取作答表的数据
            session.setAttribute("myAnswer" + c.getQ_id(), s_answer);
            if (right_answer.trim().equals(s_answer)) {//回答正确
                session.setAttribute("flag" + c.getQ_id(), "right");//设置答对的题
            } else {
                session.setAttribute("flag" + c.getQ_id(), "wrong");//设置答错的题
            }
        }
        session.setAttribute("corrected_full_marks", full_marks);
        session.setAttribute("corrected_exam_name", name);
        session.setAttribute("student_name", student.getS_name());
        return true;
    }

    //教师查看学生批改过的试卷
    @RequestMapping(value = "/teacherToCorrectedExam")
    @ResponseBody
    public Boolean teacherToCorrectedExam(HttpSession session, String name, String s_id, String s_name) throws
            IOException {
        int s_idd = Integer.parseInt(s_id.trim());
        int p_id = sqlSession.selectOne("mapper.Paper.findPaperIdByName", name.trim());//获取试卷id
        List<Point> exam_contents = sqlSession.selectList("mapper.Point.findMyExamContents", p_id);//批改后的的试卷的内容
        session.setAttribute("corrected_exam_contents", exam_contents);
        float full_marks = 0;//满分
        for (Point c : exam_contents) {
            full_marks += c.getMark();//计算满分
            String right_answer = sqlSession.selectOne("mapper.Question.searchQ_Standard", c.getQ_id());//找到该题目的正确答案
            Answer answer = new Answer();
            answer.setS_id(s_idd);//设置学号
            answer.setQ_id(c.getQ_id());//设置题号
            answer.setP_id(p_id);//设置试卷号
            String s_answer = sqlSession.selectOne("mapper.Answer.SearchAnswer", answer);//获取作答表的数据
            session.setAttribute("myAnswer" + c.getQ_id(), s_answer);
            if (right_answer.trim().equals(s_answer)) {//回答正确
                session.setAttribute("flag" + c.getQ_id(), "right");//设置答对的题
            } else {
                session.setAttribute("flag" + c.getQ_id(), "wrong");//设置答错的题
            }
        }
        session.setAttribute("corrected_full_marks", full_marks);
        session.setAttribute("corrected_exam_name", name);
        session.setAttribute("student_name", s_name);
        return true;
    }

    //获取老师要修改的学生成绩的相关信息
    @RequestMapping(value = "/changeInfo")
    @ResponseBody
    public Boolean changeInfo(HttpSession session, String name, String s_id, String s_name) throws IOException {
        session.setAttribute("changeInfo_p_name", name);//只有当教师点击确定之后这些值才有用
        session.setAttribute("changeInfo_s_id", s_id);
        return true;
    }


    //根据老师要修改的学生成绩的相关信息，修改成绩
    @RequestMapping(value = "/changeScore")
    @ResponseBody
    public Boolean changeScore(HttpSession session, String score1) throws IOException {
        String changeInfo_p_name = session.getAttribute("changeInfo_p_name").toString().trim();//试卷名称
        int changeInfo_p_id = sqlSession.selectOne("mapper.Paper.findPaperIdByName", changeInfo_p_name);//通过试卷名称找到试卷id
        int changeInfo_s_id = Integer.parseInt(session.getAttribute("changeInfo_s_id").toString().trim());//学号
        float score = Float.parseFloat(score1);//成绩
        Score sc = new Score();
        sc.setScore(score);
        sc.setS_id(changeInfo_s_id);
        sc.setP_id(changeInfo_p_id);
        int rows = sqlSession.update("mapper.Score.UpdateScore", sc);//更新成绩
        if (rows > 0) {
            out.println("修改成绩成功");
        } else {
            out.println("修改成绩失败");
        }
        sqlSession.commit();
        return true;
    }

    //    查看具体批改过的试卷后返回上一级
    @RequestMapping("/goBack")
    public String goBack(HttpSession session) {
        if (session.getAttribute("identity").toString().trim() == "teacher") {//教师页面
            return "teacher_search_score.jsp";
        } else if (session.getAttribute("identity").toString().trim() == "student") {//学生页面
            return "student_score.jsp";
        }
        return "student_score.jsp";
    }

}
